home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Documentation / DirectX9 / directx9_c.chm / directx / code / codedeco.htc < prev    next >
Encoding:
HTML Component  |  2004-09-30  |  8.9 KB  |  300 lines

  1. <PUBLIC:COMPONENT>
  2.  
  3. <PUBLIC:ATTACH EVENT="ondocumentready" HANDLER="handle_docready" />
  4.  
  5. <PUBLIC:PROPERTY NAME="AUTOHILITE" INTERNALNAME="m_bAutoHilite" HELPSTRING="Allows the author to restrict the behavior to processing the element to which it is attached; otherwise the entire document is processed." />
  6. <PUBLIC:PROPERTY NAME="TOPICNAME" INTERNALNAME="m_sTopicName" HELPSTRING="Sets or retrieves the name of the topic if the topic documents a reference page" />
  7. <PUBLIC:PROPERTY NAME="PERSISTENTNAME" INTERNALNAME="m_sPN" HELPSTRING="Sets or retrieves the persistent name of the topic if the topic documents a reference page" />
  8. <PUBLIC:PROPERTY NAME="COMMENTMARKERCOLOR" INTERNALNAME="m_sMarkerColor" HELPSTRING="Sets or retrieves the comment marker color" />
  9. <PUBLIC:PROPERTY NAME="COMMENTTEXTCOLOR" INTERNALNAME="m_sTextColor" HELPSTRING="Sets or retrieves the comment text color" />
  10.  
  11. <SCRIPT>
  12. /*
  13. The behavior's job is to decorate a syntax block.
  14. The behavior works in two modes: decorate the current element, or decorate all PREs marked with the AUTOHILITE expando.
  15.  
  16. The advantage to the latter mode is that only a single instance of the behavior need be attached to process the entire document.
  17. This works well when the document uses consistent markup for sample code. Attaching one behavior per element wastes resources unnecessarily.
  18.  
  19. The behavior exposes TOPICNAME and PERSISTENTNAME properties so that the author doesn't have to specify these in the HILITE expando of every 
  20. element to be decorated. It's up to the user to set these expandos prior to attaching the behavior.
  21.  
  22. Future enhancements:
  23. 1) In batch mode, rather than processing PREs only, expose a property ELEMENTSTODECORATE that specifies a 
  24.     semi-colon delimited list of tags that should be inspected for the AUTOHILITE attribute
  25. 2) Expose distinct properties for the different marker/text colors
  26. */
  27.  
  28. var m_sTopicName = null; // runtime name of the topic
  29. var m_sPN = null; // persistent name of the topic
  30. var m_oRng = null; // TextRange representing the current element
  31. var m_sBM = null; // TextRange bookmark
  32. var m_bAutoHilite = false; // indicates that we should decorate the current element only
  33. var m_sMarkerColor = "blue"; // color for comment delimeters
  34. var m_sTextColor = "green"; // color for text within comments
  35. var m_bScriptPage = false;//Indicates if the page is a script page
  36.  
  37. function handle_docready()
  38. {
  39.     m_oRng = window.document.body.createTextRange();
  40.     if (!m_oRng)
  41.     {
  42.         return;
  43.     }
  44.     var colMeta=window.document.all.tags("META");
  45.     if (colMeta)
  46.     {
  47.         for (var iMETAs=0; iMETAs<colMeta.length; iMETAs++)
  48.         {
  49.             if (colMeta[iMETAs].getAttribute("content")=="'scr'" && colMeta[iMETAs].getAttribute("name")=="devlang")
  50.             {
  51.                 m_bScriptPage=true;
  52.             }
  53.         }
  54.     }
  55.     if (m_bAutoHilite) // we're attached directly to the element we've been asked to hilite
  56.     {
  57.         DecorateElement(element);
  58.     }
  59.     else
  60.     {
  61.         // walk the entire topic, and decorate special block elements
  62.         var oPREs = window.document.all.tags("PRE");
  63.         var iPREs = oPREs.length;
  64.         if (iPREs == 0)
  65.         {
  66.             return;
  67.         }
  68.  
  69.         for (var iPRE = 0; iPRE < iPREs; iPRE++)
  70.         {
  71.             var oPRE = oPREs[iPRE];
  72.  
  73.             // only auto-hilite the contents if the feature has been enabled for this PRE
  74.             if (oPRE.getAttribute("AUTOHILITE"))
  75.             {
  76.                 DecorateElement(oPRE);
  77.             }
  78.         }
  79.     }
  80.  
  81. }
  82.  
  83. function DecorateElement(oElem)
  84. {
  85.     m_oRng.moveToElementText(oElem);
  86.     m_sBM = m_oRng.getBookmark(); // save our place in case we have to move the range
  87.     HiliteComments(m_oRng);
  88.     HiliteTokens(oElem, m_oRng);
  89.     if (oElem.previousSibling && oElem.previousSibling.ShowHideType )
  90.     {
  91.       toggle(oElem.previousSibling);
  92.     }
  93. }
  94.  
  95. // restore our place
  96. function RestoreRange()
  97. {
  98.     m_oRng.moveToBookmark(m_sBM);
  99. }
  100.  
  101. // Dispatch calls to the various routines that hilite different code comment types
  102. function HiliteComments(oRng)
  103. {
  104.     HiliteCStyleComments(oRng);
  105.     HiliteSingleLineComment(oRng, "//");
  106.     if (m_bScriptPage) 
  107.     {
  108.         HiliteHTMLComments(oRng);
  109.     }
  110. //    HiliteSingleLineComment(oRng, "'");
  111. }
  112.  
  113. // Hilites comments of the following form
  114. //      // C++ or JScript comment
  115. //      '  VB(S) comment
  116. //      # Perl(Script) comment
  117. function HiliteSingleLineComment(oRng, sToken)
  118. {
  119.     if (typeof(sToken) != "string")
  120.     {
  121.         return;
  122.     }
  123.  
  124.     var oRngStart = oRng.duplicate();
  125.     var oRngEnd;
  126.  
  127.     while (oRngStart.findText(sToken, 1000000) && oRng.inRange(oRngStart))
  128.     {
  129.         // handle exceptions
  130.         if (sToken == "//")
  131.         {
  132.             var sBM = oRngStart.getBookmark();
  133.             oRngStart.move("character", -1);
  134.             oRngStart.moveEnd("character", 1);
  135.             var sPrecedingChar = oRngStart.text;            
  136.             oRngStart.moveToBookmark(sBM);
  137.             if (sPrecedingChar == ":") // the token is likely part of an http (or some other protocol) link
  138.             {
  139.                oRngStart.collapse(false);
  140.                continue;
  141.             }
  142.             else if (sPrecedingChar == "-") // part of a DOCTYPE decl?
  143.             {
  144.                 oRngStart.move("character", -2);
  145.                 oRngStart.moveEnd("character", 1);
  146.                 var sQuote = oRngStart.text;
  147.                 if (/(["'])/.test(sQuote))
  148.                 {
  149.                     oRngStart.collapse(false);
  150.                     if (oRngStart.findText(RegExp.$1)) // look for matching quote at the end of the DOCTYPE
  151.                     {
  152.                         oRngStart.collapse(false);
  153.                         continue;
  154.                     }
  155.                     else
  156.                     {
  157.                         // bad news
  158.                         return;
  159.                     }
  160.                 }
  161.                 else
  162.                 {
  163.                     oRngStart.moveToBookmark(sBM); // reset and proceed
  164.                 }
  165.             }
  166.         }
  167.         
  168.         oRngStart.execCommand("ForeColor", false, m_sMarkerColor);
  169.         oRngStart.collapse(false);    
  170.         oRngEnd = oRngStart.duplicate();
  171.         if (oRngEnd.findText("\r", 1000000))
  172.         {
  173.             oRngStart.setEndPoint("EndToStart", oRngEnd);
  174.         }
  175.         else
  176.         {
  177.             // comment is the last line in the block
  178.             oRngStart.setEndPoint("EndToEnd", oRng);
  179.         }
  180.         oRngStart.execCommand("ForeColor", false, m_sTextColor);
  181.     }
  182.  
  183. }
  184.  
  185. // Hilite C-style comments in the specified range
  186. function HiliteCStyleComments(oRng)
  187. {
  188.     var oRngStart = oRng.duplicate();
  189.     var oRngEnd;
  190.  
  191.     while (oRngStart.findText("/*", 1000000) && oRng.inRange(oRngStart))
  192.     {
  193.         oRngStart.execCommand("ForeColor", false, m_sMarkerColor);
  194.         oRngStart.collapse(false);    
  195.         oRngEnd = oRngStart.duplicate();
  196.         if (!oRngEnd.findText("*/", 1000000))
  197.         {
  198.             break; // bad news; couldn't find closing comment. Bail.
  199.         }
  200.         oRngEnd.execCommand("ForeColor", false, m_sMarkerColor);
  201.         oRngStart.setEndPoint("EndToStart", oRngEnd);
  202.         oRngStart.execCommand("ForeColor", false, m_sTextColor);
  203.     }
  204. }
  205.  
  206. // Hilite HTML-style comments in the specified range
  207. function HiliteHTMLComments(oRng)
  208. {
  209.     var oRngStart = oRng.duplicate();
  210.     var oRngEnd;
  211.     while (oRngStart.findText("<!--") && oRng.inRange(oRngStart))
  212.     {
  213.         // Check for a conditional IE comment
  214.         oRngStart.setEndPoint( "EndToEnd", oRng );
  215.         if ( /<!--\s*\[\s*if/.test( oRngStart.text ) )
  216.         {
  217.             oRngEnd = oRngStart.duplicate();
  218.             if ( oRngEnd.findText( ">" ) )
  219.             {    // Skip conditional comment
  220.                 oRngStart.setEndPoint( "StartToEnd", oRngEnd );
  221.             }
  222.             continue;
  223.         }
  224.         else
  225.         {    // Reset text range
  226.             oRngStart.findText("<!--");
  227.         }
  228.  
  229.         oRngStart.moveEnd("character", -2); // back up to exclude the --
  230.         oRngStart.execCommand("ForeColor", false, m_sMarkerColor);
  231.         oRngStart.collapse(false);    
  232.         oRngEnd = oRngStart.duplicate();
  233.         if (!oRngEnd.findText("-->"))
  234.         {
  235.             break; // bad news; couldn't find closing comment. Bail.
  236.         }
  237.         oRngEnd.moveStart("character", 2); // roll forward to exclude the --
  238.         oRngEnd.execCommand("ForeColor", false, m_sMarkerColor);
  239.         oRngStart.setEndPoint("EndToStart", oRngEnd);
  240.         oRngStart.execCommand("ForeColor", false, m_sTextColor); // hilite the comment text
  241.     }
  242. }
  243.  
  244. // Apply hiliting to the keywords identified in the semi-colon delimited string associated with the HILITE attribute.
  245. function HiliteTokens(oElement, oRng)
  246. {    
  247.     var oRegEmptyStr = new RegExp("^\\s*$");
  248.     
  249.     // process any author-defined tokens
  250.     var sTokens = oElement.getAttribute("HILITE");
  251.  
  252.     if (!sTokens && !m_sTopicName && !m_sPN)
  253.     {
  254.         return; // nothing to hilite
  255.     }
  256.  
  257.     var aTokens; // array of tokens to search for
  258.  
  259.     if (sTokens) 
  260.     {
  261.         aTokens = sTokens.split(";");
  262.     }
  263.     else
  264.     {
  265.         aTokens = new Array();
  266.     }
  267.  
  268.     // if available, append the topic's runtime and persistent name to the list
  269.     if (m_sTopicName) aTokens[aTokens.length] = m_sTopicName;
  270.     if (m_sPN) aTokens[aTokens.length] = m_sPN;
  271.     
  272.     var ahTokens = new Array(); // hash of tokens we've already searched for to prevent accidental toggling
  273.  
  274.     var oRngTemp = oRng.duplicate();
  275.     for (var iToken = 0; iToken < aTokens.length; iToken++)
  276.     {
  277.         var sToken = aTokens[iToken];
  278.         // watch out for dupe tokens
  279.         if (oRegEmptyStr.test(sToken) || ahTokens[sToken])
  280.         {
  281.             continue;
  282.         }
  283.  
  284.         ahTokens[sToken] = 1;
  285.  
  286.         while (oRngTemp.findText(sToken, 1000000, 6) && oRng.inRange(oRngTemp)) 
  287.         {    
  288.             oRngTemp.execCommand("bold");
  289.             oRngTemp.collapse(false);
  290.         }
  291.  
  292.         oRngTemp.moveToBookmark(m_sBM); // reset the temporary range for the next iteration
  293.  
  294.     }
  295. }
  296.  
  297. </SCRIPT>
  298.  
  299. </PUBLIC:COMPONENT>
  300.